package com.yuan.consumer;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.context.ApplicationContext;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author yuandong
 * @date 2021/5/8 9:33
 * 消费者创建一个组件监听队列
 */
@Component
@Slf4j
public class MyAckListener {

        /**
         * @param message 队列中的消息;
         * @param channel 当前的消息队列;
         * @throws IOException
         */
        @RabbitListener(queues = "hello_queue")
        @RabbitHandler
        public void myAckListener(Message message, Channel channel, String str) throws IOException {
            try {
                log.info("消费者从队列中获取到消息>>>>>>"+str);
                Thread.sleep(3000);
                log.info("业务逻辑发生错误，消息没有消费，会执行cath()语句，然后将消息重新放到队列，继续给消费者...");
                int i = 3 / 0;  //手动添加异常

                /**
                 * 确认消息，参数说明：
                 * deliveryTag：唯一标识 ID。
                 * multiple：是否批处理，当该参数为 true 时，则可以一次性确认 deliveryTag 小于等于传入值的所有消息。
                 * 实际开发使用false即可；
                 */
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }catch (Exception e){
                /**
                 * 有异常就绝收消息
                 * basicNack(long deliveryTag, boolean multiple, boolean requeue)
                 * deliveryTag：唯一标识 ID。
                 * multiple：是否批处理，当该参数为 true 时，则可以一次性确认 deliveryTag 小于等于传入值的所有消息。
                 * requeue：如果requeue 参数设置为 true，则 RabbitMQ 会重新将这条消息存入队列，以便发送给下一个订阅的消费者；
                 * requeue 参数设置为 false，则 RabbitMQ 立即会还把消息从队列中移除，而不会把它发送给新的消费者。
                 */
                log.info("消费者从队列中获取消息失败");
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
                e.printStackTrace();
            }
    }

}
